﻿using System;
using System.Threading;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

namespace ui
{
   
    public partial class Form1 : Form
    {
        private bool Write_Flag = false;               //写标志位 true时允许写
        private readonly SynchronizationContext _mContext;
        private TcpServer _server;
        private const string START = "@#;";
        private const string END = "\r\n\0";
        private const string Mode1 = "@B{0},{1},{2},{3};";  // speed mode

        private UInt32 TorqueChartStartTime = 0;
        private const string Mode2 = "@B{0},{1},{2};";  // speed mode
        private const string Mode3 = "@BT,{0},{1};"; // stop mode 
        private List<ComboBox> comboboxs = new List<ComboBox>();
        private List<Label> labels = new List<Label>();
        private List<TextBox> textBoxes1 = new List<TextBox>();
        private List<TextBox> textBoxes2 = new List<TextBox>();
        private List<TextBox> textBoxes3 = new List<TextBox>();
        private float BarMoveSpeed;
        private double NowPlace=0;               //当前抓手距离原点位置
        private double moveSpeed = 0;
        private UInt32 SecondCount = 0;       //当前动作剩余时间
        string  postPath;
        private int ButtonON = 3;
        private bool isCatch = false, isCut = false;


        public Form1()
        {
            InitializeComponent();
            _mContext = SynchronizationContext.Current;
            //将解析完成后的数据通过show函数显示
            ParseUtil.UpdateDashBoard += Show;

            this.WindowState = FormWindowState.Maximized;
            
            labels.Add(label1);
            labels.Add(label2);
            labels.Add(label3);
            textBoxes1.Add(edit11);
            textBoxes1.Add(edit21);
            textBoxes1.Add(edit31);
            textBoxes2.Add(edit12);
            textBoxes2.Add(edit22);
            textBoxes2.Add(edit32);
            textBoxes3.Add(this.TexBTorque1);
            textBoxes3.Add(this.TexBTorque2);
            textBoxes3.Add(this.TexBTorque3);
            for (int i = 0; i < comboboxs.Count; i++)
            {
                comboboxs[i].SelectedIndex = 0;
            }
        }
        /*****************************************************************************************
        *Function:Show()
        *Description:与TCP线程中数据上传委托绑定，当接收到子线程数据后通过_mContext传递给UI线程显示
        *Input:rs:TCP接收到后解析完成后交给show函数的显示数据
        *Output:None
        *Other:None
        ****************************************************************************************/
        private void Show(ParseResult rs)
        {
            //LogInfo("表盘显示");
           // _mContext.Post(LogInfo, "表盘显示");
            _mContext.Post(SetValue, rs);           //通过Post将TCP监听线程中的数据rs作为参量传给UI线程中的SetValue
            
            
        }
        /*****************************************************************************************
        *Function:SetValue()
        *Description:实际修改界面的函数
        *Input:state:由_mContext传入的数据
        *Output:None
        *Other:None
        ****************************************************************************************/
        private void SetValue(object state)
        {
            ParseResult rs = (ParseResult)state;
            string WriteFile="" ;
                       rs.Height = rs.Height * 0.0152 - 9.983;
                       rs.Temp3 = rs.Temp3 * 0.0152 - 9.983;
                       rs.Press2 = rs.Press2 * 0.0152 - 9.983;
                       rs.Press3 = rs.Press3 * 0.0152 - 9.983;

            rs.FlowRt = rs.FlowRt * 0.0192-20.5;
            rs.Temp1 = rs.Temp1 * 0.0192 - 20.5;
            rs.Temp2 = rs.Temp2 * 0.0192 - 20.5;

            //非电机启动阶段，出现扭矩过大情况，马上停止电机
            if (ButtonON == 0 && rs.Speed3>500 && (rs.Torque3 > 500 || rs.Torque3 < -500))
            {
                //设置三号电机在非启动状态下的扭矩阈值为500
                if (canSendData())
                {
                    String res = "";
                    for (int i = 0; i < textBoxes1.Count; i++)
                    {
                        res = res + stopStr(i);
                    }
                    sendData(wrapper(res));
                    LogInfo("三号电机扭矩超过阈值，紧急停止！");
                }
            }

            press1.SetValue("DigitalIndicator1", rs.Height);   //IN3
            press2.SetValue("DigitalIndicator1", rs.Temp3);   //IN4
            press3.SetValue("DigitalIndicator1", rs.Press2 );   //IN5
            press4.SetValue("DigitalIndicator1", rs.Press3 );   //IN6

            temp1.SetValue("DigitalIndicator1", rs.FlowRt);//数码管显示值         //IN7
            temp2.SetValue("DigitalIndicator1", rs.Temp1);                      //IN8
            temp3.SetValue("DigitalIndicator1", rs.Temp2);                      //IN9

            //height.SetValue("DigitalIndicator1", rs.Temp3);                     //IN10

            speed1.SetValue("DigitalIndicator1", rs.Speed1 );  
            speed2.SetValue("DigitalIndicator1", rs.Speed2 );   
            speed3.SetValue("DigitalIndicator1", rs.Speed3 );
            speed1.SetValue("Pointer1", rs.Speed1 );           //指针值
            speed2.SetValue("Pointer1", rs.Speed2 );
            speed3.SetValue("Pointer1", rs.Speed3 );

            torque1.SetValue("Pointer1", rs.Torque1);
            torque2.SetValue("Pointer1", rs.Torque2);
            torque3.SetValue("Pointer1", rs.Torque3);
            torque1.SetValue("DigitalIndicator1", rs.Torque1);
            torque2.SetValue("DigitalIndicator1", rs.Torque2);
            torque3.SetValue("DigitalIndicator1", rs.Torque3);
            if (rs.Status1 == 4663)
            {
               // Console.WriteLine("Status1接收成功");
                Ch1WorkLight.SetValue("ImageStateIndicator1", 0);
            }
            else 
                Ch1WorkLight.SetValue("ImageStateIndicator1", 1);
            if(rs.Status2 == 4663)
            {
               // Console.WriteLine("Status2接收成功");
                Ch2WorkLight.SetValue("ImageStateIndicator1", 0);
            }
            else
                Ch2WorkLight.SetValue("ImageStateIndicator1", 1);
            if (rs.Status3 == 567)
            {
              //  Console.WriteLine("Status3接收成功");
                Ch3WorkLight.SetValue("ImageStateIndicator1", 0);
            }
            else
                Ch3WorkLight.SetValue("ImageStateIndicator1", 1); 
            if (rs.Status1 == 536||rs.Status2==576||rs.Status1==8728||rs.Status2==8728)
            {
               // 一二号电机运行出错
                ErrorLight.SetValue("ImageStateIndicator1", 0);
            }
            else
                ErrorLight.SetValue("ImageStateIndicator1", 1);
            WriteFile += rs.Height.ToString("0.00")+" ;";
            WriteFile += rs.Temp3.ToString("0.00") + "; " ;
            WriteFile += rs.Press2.ToString("0.00") + " ;" ;
            WriteFile += rs.Press3.ToString("0.00") + " ;" ;
            WriteFile += rs.FlowRt.ToString("0.0") + " ;"  ;
            WriteFile += rs.Temp1.ToString("0.0") + " ;" ;
            WriteFile += rs.Temp2.ToString("0.0") ;

            if (Write_Flag == true) WriteData(WriteFile);
            //Console.WriteLine("WriteData" + WriteFile);
        }
        /*****************************************************************************************
        *Function:WriteData()
        *Description:接收后储存到安装目录
        *Input:state:res：接收到的数据
        *Output:None
        *Other:
        ****************************************************************************************/
        private void WriteData(string res)
        {
            
            StreamWriter sw = new StreamWriter(postPath, true);
            //开始写
            sw.WriteLine(res.ToString());
            
            //清空缓存
            sw.Flush();
            //关闭流
            sw.Close();
            
        }
        /*****************************************************************************************
        *Function:LogShow()
        *Description:与TCP线程中的LogShow绑定，调用时通过_mContext将数据从子线程传递到UI线程
        *Input:state:s：TCP接收到处理后要显示的数据
        *Output:None
        *Other:LogInfo 实际主线程中修改界面的函数
        ****************************************************************************************/
        private void LogShow(string s)
        {
            _mContext.Post(LogInfo,"状态信息:"+ s);
        }
        
        /*****************************************************************************************
        *Function:connect_Click()
        *Description:RJ45连接按钮事件，
        *Input:Chanal:None
        *Output:None
        *Other:目标IP 192.168.1.30,目标端口号8088
        ****************************************************************************************/
        private void LogInfo(object state)
        {
            var timeNow = DateTime.Now.ToLongTimeString();
            logBox.AppendText(timeNow + " ");
            logBox.AppendText((string)state);
            logBox.AppendText(Environment.NewLine);
        }
        
        /*****************************************************************************************
        *Function:connect_Click()
        *Description:RJ45连接按钮事件，
        *Input:Chanal:None
        *Output:None
        *Other:目标IP 192.168.1.30,目标端口号8088
        ****************************************************************************************/
        private void connect_Click(object sender, EventArgs e)
        {
            if (_server == null || _server.State == 3 )
            {
                 _server = new TcpServer("192.168.1.30", 8088);
                _server.LogShow += LogShow;
                var t = new Thread(_server.Start) { IsBackground = true };
                t.Start();                  //启动TCP线程

            }
            else if (_server.State == 1)
            {
                LogInfo("Connecting.");
            }
            else if (_server.State == 2 )
            {

                LogInfo("Connected.");

            }

        }

        
        /*****************************************************************************************
        *Function:check_send()
        *Description:读取各通道的输入值，将四个通道的数据封装成一帧数据帧
        *Input:Chanal:None
        *Output:None
        *Other:三通道输入的是实际需要运动的距离，距离转电机运动圈数比为1：5故需要单独乘5后发送
        ****************************************************************************************/
        private string check_send(int index)
        {
            string res = "";
            string tmp = textBoxes1[index].Text;
            String temp;
            if (index !=2 || textBoxes2[2].Text=="")                   //第三通道发送具体距离为空或其他通道直接发送字符串
            {
                temp = textBoxes2[index].Text;
            }
            else { 
            int Count =int.Parse(textBoxes2[index].Text);        //距离值转换为具体圈数
                Count *= 5;
                temp = Count.ToString();
            }
            string mode =  "P";
            if (tmp != null && temp != null && temp.Length != 0 && tmp.Length != 0)
            {
                res = String.Format(Mode1, mode,index + 1, tmp, temp);
            }
            return res;
        }
        /*****************************************************************************************
        *Function:TorqueSend()
        *Description:发送扭矩数据帧，将指定通道的扭矩封装
        *Input:Chanal:index：扭矩发送通道
        *Output:None
        *Other:None
        ****************************************************************************************/
        private string TorqueSend(int index)
        {
            string res = "";
            string temp = textBoxes3[index-1].Text;
            
            string mode = "R";
            if (temp != null && temp.Length != 0 )
            {
                res = String.Format(Mode2, mode, index ,temp);
            }

            return res;
        }
        private bool canSendData()
        {
            return _server != null && _server.State == 2;
        }
        /*****************************************************************************************
         *Function: AllChnnelSend()
         *Description:按照四个通道的当前数据
         *Input:Chanal :要移动的距离,移动速度由三号电机速度决定
         *Output:None
         *Other:
         * ***************************************************************************************/
        private void AllChnnelSend()
        {
            if(canSendData())
            {

                string res = "";
                for (int i = 0; i <textBoxes1.Count; i++)
                {
                    res = res + check_send(i);
                }

                res = wrapper(res);
                sendData(res);
            }
            else
            {
                LogInfo("Please connect first.");
            }
        }
        /*****************************************************************************************
         *Function: SendMove()
         *Description:向三号电机发送要移动的距离指令
         *Input:Chanal :要移动的距离,移动速度由三号电机速度决定，长度以毫米为单位
         *Output:None
         *Other:
         * ***************************************************************************************/
        private void SendMove(Int32 Length)
        {
            if (canSendData())
            {
                //设置电机启动3秒内为无视扭矩大小时间
                ButtonON = 2;
                if (Length < 0)
                    moveSpeed = double.Parse(edit31.Text.ToString()) / 300;
                else
                    moveSpeed = double.Parse(edit31.Text.ToString()) / -300;
               // LogInfo("speed=" + moveSpeed.ToString());
                Length = 5*Length;
                string res = "";
                string RealCount= Length.ToString();
                string mode = "P";
                if (Length>=-25000&&Length <=25000)
                {
                    res = String.Format(Mode1, mode, 3, textBoxes1[2].Text,RealCount);
                }
                res = wrapper(res);
                sendData(res);
            }
            else
            {
                LogInfo("Please connect first.");
            }
        }
        /*****************************************************************************************
         *Function: TorqueValueSend()
         *Description:将扭矩值封装成一帧数据帧
         *Input:Chanal :要发送的电机号
         *Output:None
         * Other:
         ****************************************************************************************/
        private void TorqueValueSend(UInt16 Chanal)
        {
            if (canSendData())
            {

                string res = "";
               res = res + TorqueSend(Chanal);
                res = wrapper(res);
                sendData(res);
            }
            else
            {
                LogInfo("Please connect first.");
            }
        }
        /*****************************************************************************************
        *Function:wrapper()
        *Description:为数据帧添加帧头和帧尾
        *Input:Chanal:None
        *Output:None
        *Other:None
        ****************************************************************************************/
        private string wrapper(string content)
        {
            return START + content + END;
        }

        

        private void close_Click(object sender, EventArgs e)
        {
            _server.Stop();
        }



        private void sendBtn_Click(object sender, EventArgs e)
        {
            AllChnnelSend();
            if (string.IsNullOrEmpty(edit32.Text.Trim()))
                SecondCount = 0;
            else
            {
                SecondCount = CalculateSecondCount(uint.Parse(edit31.Text.ToString()), int.Parse(edit32.Text.ToString())); //计算移动秒
                
           
                //计算移动速度
                if (int.Parse(edit32.Text.ToString()) < 0)
                    moveSpeed = double.Parse(edit31.Text.ToString()) / 300;
                else
                    moveSpeed = double.Parse(edit31.Text.ToString()) / -300;
                
                timer1.Start();
            }


        }


        private void sendData(string data)
        {
            LogInfo(data);
            _server.Send(data);
        }

        private string stopStr(int index)
        {
            return String.Format(Mode3, index + 1, 1);
        }

        private string ClearStr(int index)
        {
            return String.Format(Mode3, index + 1, 2);
        }

        private string BackStr(int index)
        {
            return String.Format(Mode3, index + 1, 3);
        }

        private void stopOne(int index)
        {
            if (canSendData())
            {
                sendData(wrapper(stopStr(index)));
            }
        }

        private void ClearOne(int index)
        {
            if (canSendData())
            {
                sendData(wrapper(ClearStr(index)));
            }
        }
        private void BackOne(int index)
        {
            if (canSendData())
            {
                sendData(wrapper(BackStr(index)));
            }
        }

        private void stopAllBtn_Click(object sender, EventArgs e)
        {
            if (canSendData())
            {

                SecondCount = 0; //停止运行，剩余时间清零
                String res = "";
                for (int i = 0; i < textBoxes1.Count; i++)
                {
                    res = res + stopStr(i);
                }
                sendData(wrapper(res));
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            stopOne(0);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            stopOne(1);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            stopOne(2);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            stopOne(3);
        }

        private void BtnCLear1_Click(object sender, EventArgs e)
        {
            ClearOne(0);
        }

        private void BtnCLear2_Click(object sender, EventArgs e)
        {
            ClearOne(1);
        }

        private void BtnCLear3_Click(object sender, EventArgs e)
        {
            ClearOne(2);
        }

        private void BtnCLear4_Click(object sender, EventArgs e)
        {
            ClearOne(3);
        }
        /*****************************************************************************************
        *Function:CutBack_Click()
        *Description:紧急退刀按钮触发事件
        *Input:None
        *Output:None
        * Other:None
        * ***************************************************************************************/
        private void CutBack_Click(object sender, EventArgs e)
        {
           // button6.Image = global::ui.Properties.Resources.;
            BackOne(0);
        }
        /*****************************************************************************************
         *Function:BtnIn_Click()
         *Description:进刀按钮触发事件
         *Input:None
         *Output:None
         * Other:None
         * ***************************************************************************************/
        private void BtnIn_Click(object sender, EventArgs e)
        {
            pictureBox3.Image = global::ui.Properties.Resources.Cut;
            pictureBox7.Image = global::ui.Properties.Resources.clamp ;
            userControl1.CutFlag = true;
            userControl1.IsCutRockLength = int.Parse(CutLength.Text) /(float)59.55;
            userControl1.RockLength -= userControl1.IsCutRockLength;
            isCut = true;
            userControl1.IsCutRockStartPosition = userControl1.Value + userControl1.RockLength; //被切部分跟随移动
            SecondCount = 120;
            moveSpeed = 0;
            timer1.Start();
            if (canSendData())
            {
                string res = "";
                res = res + "@BP,1,2295,-4590;@BP,2,1620,3240;";
                sendData(wrapper(res));
            }
        }
        
        /*****************************************************************************************
         *Function:BtnBack_Click()
         *Description:退刀按钮触发事件
         *Input:None
         *Output:None
         * Other:None
         * ***************************************************************************************/
        private void BtnBack_Click(object sender, EventArgs e)
        {
            pictureBox3.Image = global::ui.Properties.Resources.unCut;
            pictureBox7.Image = global::ui.Properties.Resources.unclamp;
            SecondCount = 60;
            moveSpeed = 0;
            timer1.Start();
            if (canSendData())
            {
                //SecondCount = 60;
                string res = "";
                res = res + "@BP,1,1350,1350;";
                sendData(wrapper(res));
            }
        }
        
        /*****************************************************************************************
         *Function:Button7_Click()
         *Description:3mm按钮触发事件
         *Input:None
         *Output:None
         * Other:None
         * ***************************************************************************************/
        private void Button7_Click(object sender, EventArgs e)
        {
            if (canSendData())
            {
                string res = "";
                res = res + "@BP,1,540,81;";
                sendData(wrapper(res));
            }
        }

        
        /*****************************************************************************************
         *Function:RunShow_Click()
         *Description:用于演示模拟抓取控件的运行
         *Input:None
         *Output:None
         * Other:None
         * ***************************************************************************************/
        private void RunShow_Click(object sender, EventArgs e)
        {
            userControl1.Value = 30;
            this.userControl1.RockLength = 50;
            this.userControl1.RockStartPosition = 70;
            userControl1.IsCutRockStartPosition = 60;
            userControl1.IsCutRockLength = 10;
            this.userControl1.CutFlag = false;
            this.userControl1.CatchFlag = false;
            this.timer1.Start();
        }
        /*****************************************************************************************
         *Function: CalculateSecondCount()
         *Description:计算一次移动所需要的时间数，以秒为单位
         *Input:Speed：移动的速度，Length:需要移动的长度 以毫米为单位
         *Output:SecountCount:本次移动所需要的秒数
         *Other：None
         ****************************************************************************************/
        private UInt32 CalculateSecondCount(UInt32 Speed, int Length=0)
        {
            UInt32 SecondCount;
            if (Length < 0) Length = 0 - Length;
            SecondCount = Convert.ToUInt32(((Length * 5.0) / Speed) * 60);
            return SecondCount;
        }
        /*****************************************************************************************
         *Function: RunShow_Task()
         *Description:定时器Timer1的定时事件触发任务
         *Input:None
         *Output:None
         * Other:None
         * ***************************************************************************************/
        private void RunShow_Task(object sender, EventArgs e)
        {
            //电机启动时扭矩过大时间倒计时
            if (ButtonON != 0) ButtonON--;
            //运动剩余时间减一
            if (SecondCount != 0)
            {
                SecondCount--;
                ShowSecondCount.SetValue("DigitalIndicator1", SecondCount);
                //计算当前位置
                NowPlace += moveSpeed;
                ShowNowPlace.SetValue("DigitalIndicator1", NowPlace / 10);

                //动画移动
                userControl1.Value = (float)NowPlace / (float)59.56;
                if (isCatch)
                {
                    userControl1.RockStartPosition = userControl1.Value;//岩芯跟随移动
                }
                if (isCut)
                {
                    userControl1.IsCutRockStartPosition = userControl1.Value + userControl1.RockLength; //被切部分跟随移动
                }
                //设置抓手移动范围
                if (NowPlace < 100 && moveSpeed < 0)
                {
                    LogInfo("紧急停止！超出移动范围！");
                    //发送急停指令
                    if (canSendData())
                    {
                        String res = "";
                        for (int i = 0; i < textBoxes1.Count; i++)
                        {
                            res = res + stopStr(i);
                        }
                        sendData(wrapper(res));
                    }
                    timer1.Stop();
                }
                if (NowPlace > 5380 && moveSpeed > 0)
                {
                    LogInfo("紧急停止！超出移动范围！");
                    //发送急停指令
                    if (canSendData())
                    {
                        String res = "";
                        for (int i = 0; i < textBoxes1.Count; i++)
                        {
                            res = res + stopStr(i);
                        }
                        sendData(wrapper(res));
                    }
                    timer1.Stop();
                }

            }
            else
                timer1.Stop(); //动画运行结束



           
        }

        /*****************************************************************************************
         *Function: CutRock_Click()
         *Description:根据输入的要切割长度，调整三号电机移动
         *Input:None
         *Output:None
         *Other:1076为默认基础距离
         ****************************************************************************************/

        private void ButTorque1_Click(object sender, EventArgs e)
        {
            TorqueValueSend(1);
        }

        private void ButTorque2_Click(object sender, EventArgs e)
        {
            TorqueValueSend(2);
        }

        private void ButTorque3_Click(object sender, EventArgs e)
        {
            TorqueValueSend(3);
        }

        private void ButTorque4_Click(object sender, EventArgs e)
        {
            TorqueValueSend(4);
        }

        /*****************************************************************************************
         *Function: CutRock_Click()
         *Description:根据输入的要切割长度，调整三号电机移动
         *Input:None
         *Output:None
         *Other:1076为默认基础距离
         ****************************************************************************************/
        private void CutRock_Click(object sender, EventArgs e)
        {
            Int32 Cutlength, Move;
            Cutlength = int.Parse(this.CutLength.Text);
            Move = 1072 - Cutlength;
            SecondCount=CalculateSecondCount(uint.Parse(edit31.Text.ToString()), (int)System.Math.Abs(Move));
            SendMove(Move);
            timer1.Start();
        }
        /*****************************************************************************************
         *Function: ButCatch_Click()
         *Description:三号电机按指定长度抓取
         *Input:None
         *Output:None
         *Other:None
         ****************************************************************************************/
        private void ButCatch_Click(object sender, EventArgs e)
        {
            SecondCount=CalculateSecondCount(uint.Parse(edit31.Text.ToString()), int.Parse(CatchLength.Text.ToString()));
            String Length = "-" + CatchLength.Text;
            SendMove(int.Parse(Length));
            
            timer1.Start();
        }
        /*****************************************************************************************
         *Function: CatchBack_Click()
         *Description:抓取完成后三号电机按指定长度回退
         *Input:None
         *Output:None
         * Other:None
         * ***************************************************************************************/
        private void CatchBack_Click(object sender, EventArgs e)
        {
            SecondCount=CalculateSecondCount(uint.Parse(edit31.Text.ToString()), int.Parse(CatchLength.Text.ToString()));
            isCatch = true;
            SendMove(int.Parse(CatchLength.Text));
            timer1.Start();
        }
        /*****************************************************************************************
         *Function: CatchBack_Click()
         *Description:人工确认抓取完成后，继续向CT方向回退到CT扫描完成
         *Input:None
         *Output:None
         * Other:回退方向为正方向
         * ***************************************************************************************/
        private void CTScan_Click(object sender, EventArgs e)
        {
            SecondCount=CalculateSecondCount(uint.Parse(edit31.Text.ToString()), int.Parse(CTBackeLength.Text.ToString()));
            timer1.Start();
            SendMove(int.Parse(CTBackeLength.Text));
        }
        /*****************************************************************************************
         *Function: PullOut_Click()
         *Description:切割完成后将被切部分先推至CT扫描位置
         *Input:None
         *Output:None
         * Other：None
         ****************************************************************************************/
        private void PullOut_Click(object sender, EventArgs e)
        {
            SecondCount = CalculateSecondCount(uint.Parse(edit31.Text.ToString()), 1076);
            String PullLength = "-" + CTBackeLength.Text;
            SendMove(-1076);
            timer1.Start();
        }
        /*****************************************************************************************
         *Function:TorqueChartShow()
         *Description:用于动态显示曲线图
         *Input:None
         *Output:None
         * Other：在UpdateUiDelegate委托中，每次接收到数据执行
         * ***************************************************************************************/
        private void TorqueChartShow(ParseResult rs)
        {
            TorqueChart1.AddPlotPoint("Channel1", TorqueChartStartTime, rs.Torque1);
            TorqueChart2.AddPlotPoint("Channel1", TorqueChartStartTime, rs.Torque2);
            TorqueChart3.AddPlotPoint("Channel1", TorqueChartStartTime, rs.Torque3);
            TorqueChart4.AddPlotPoint("Channel1", TorqueChartStartTime, rs.Torque4);
            TorqueChartStartTime += 1;
        }
        /*****************************************************************************************
         *Function: TabControlChanged()
         *Description:TabControl索引改变事件触发函数，判断当前的索引页做出具体操作
         *Input:None
         *Output:None
         * Other：在UpdateUiDelegate委托中，每次接收到数据执行,曲线图实时显示窗口索引号为2
        * ***************************************************************************************/
        private void TabControlChanged(object sender, EventArgs e)
        {
            CatchLength.Text = MyTabControl2.SelectedIndex.ToString();
            if (MyTabControl2.SelectedIndex  == 1)
            {
                ParseUtil.UpdateDashBoard += TorqueChartShow;
            }
            else
            { 
                ParseUtil.UpdateDashBoard -= TorqueChartShow;
            }
        }

        private void ButDisconnect_Click(object sender, EventArgs e)
        {
            _server.Stop();
            Ch1WorkLight.SetValue("ImageStateIndicator1", 1);
            Ch2WorkLight.SetValue("ImageStateIndicator1", 1);
            Ch3WorkLight.SetValue("ImageStateIndicator1", 1);
            ErrorLight.SetValue("ImageStateIndicator1", 1);
        }

        private void CTScanStart_Click(object sender, EventArgs e)
        {
            SecondCount=CalculateSecondCount(uint.Parse(edit31.Text.ToString()), 57);
            
            SendMove(57);//每次移动5.7厘米
            timer1.Start();
        }

        private void button11_Click(object sender, EventArgs e)
        {
            pictureBox3.Image = global::ui.Properties.Resources.Cut;
            pictureBox7.Image = global::ui.Properties.Resources.clamp;
            userControl1.CutFlag = true;
            userControl1.IsCutRockLength = int.Parse(CutLength.Text) / 100;
            userControl1.RockLength -= userControl1.IsCutRockLength;
            userControl1.IsCutRockStartPosition = 60;
            if (canSendData())
            {
                string res = "";
                res = res + "@BP,1,2295,-9180;@BP,2,1620,6480;";
                sendData(wrapper(res));
            }
        }

        private void button10_Click(object sender, EventArgs e)
        {
            if (canSendData())
            {
                string res = "";
                res = res + "@BP,1,540,162;";
                sendData(wrapper(res));
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            pictureBox3.Image = global::ui.Properties.Resources.unCut;
            pictureBox7.Image = global::ui.Properties.Resources.unclamp;
            if (canSendData())
            {
                string res = "";
                res = res + "@BP,1,1350,2700;";
                sendData(wrapper(res));
            }
        }
        /*****************************************************************************************
         *Function: button12_Click()
         *Description:button12点击事件触发函数，将被切的岩芯重新推入岩芯管,然后抓手回到CT扫描末端
         *Input:None
         *Output:None
         * Other：None
        * ***************************************************************************************/
        private void button12_Click(object sender, EventArgs e)
        {
            SecondCount = CalculateSecondCount(uint.Parse(edit31.Text.ToString()), 1040);
            SendMove(-1040);
            timer1.Start();
        }

        private void button13_Click(object sender, EventArgs e)
        {
            SecondCount = CalculateSecondCount(uint.Parse(edit31.Text.ToString()), 1040);
            userControl1.CutFlag = false;
            SendMove(1040);
            timer1.Start();
        }

        private void button15_Click(object sender, EventArgs e)
        {

            if (Write_Flag == false)
            {
                this.button15.Text = "保存结束";
                Write_Flag = true;
                string path = System.Windows.Forms.Application.StartupPath + "\\DownFile\\";
                if (!Directory.Exists(path))

                {

                    Directory.CreateDirectory(path);

                }                  //判断文件夹是否存在
                postPath = path + DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";//路径+文件名
                //Console.WriteLine(postPath);
                //WriteFileStream = new FileStream(@"E:\11111.txt", FileMode.CreateNew);
            }
            else
            {
                Write_Flag = false;
                this.button15.Text = "保存文件";
            }
              
        }
        /*****************************************************************************************
         *Function: Place_init_button_Click()
         *Description:系统启动前现将抓手调整到CT中心位置，点击位置初校准后会将软件初始位置重新定位到CT中心动画匹配
         **Input:None
         *Output:None
         * Other：None
         ****************************************************************************************/
        private void Place_init_button_Click(object sender, EventArgs e)
        {
            NowPlace = 3730;
            userControl1.Value = (float)NowPlace / (float)59.56;
            userControl1.RockStartPosition = 90;
            ShowSecondCount.SetValue("DigitalIndicator1", SecondCount);
            ShowNowPlace.SetValue("DigitalIndicator1", NowPlace/10);
            isCatch = false;
            isCut = false;
        }
    }
}
